﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Input;
using GalaSoft.MvvmLight.Command;
using MSH.Common.DAO;
using MSH.Common.DAO.Results;
using WP7Client.Helpers;
using WP7Client.ServerManager;
using System.Windows;
using WP7Client.Managers;
using MSH.Common.Classes;

namespace WP7Client.Controller
{
    public class FriendController : BaseController
    {
        #region Members


        #endregion

        #region Get&Set

        public ICommand ShowProfileCommand 
        { 
            get; 
            internal set; 
        }

        public ICommand ChatCommand 
        { 
            get; 
            internal set; 
        }

        public ICommand RemoveFriendCommand
        {
            get;
            internal set;
        }

        public ICommand BlockFriendCommand
        {
            get;
            internal set;
        }

        public ICommand UnblockFriendCommand
        {
            get;
            internal set;
        }

        public ICommand ShowFriendsOnMapCommand
        {
            get;
            internal set;
        }

        public ICommand FriendNotificationCommand
        {
            get;
            internal set;
        }

        private ObservableCollection<Friend> _Friends = new ObservableCollection<Friend>();
        public ObservableCollection<Friend> Friends
        {
            get { return _Friends; }
            set { 
                _Friends = value; 
                OnPropertyChanged("Friends");
            }
        }

        #endregion       

        public FriendController()
        {
            ShowProfileCommand = new RelayCommand<Object>(DoShowProfile);
            ChatCommand = new RelayCommand<String>(Chat);
            RemoveFriendCommand = new RelayCommand<String>(RemoveFriend);
            BlockFriendCommand = new RelayCommand<String>(BlockFriend);
            UnblockFriendCommand = new RelayCommand<String>(UnblockFriend);
            ShowFriendsOnMapCommand = new RelayCommand(ShowFriendsOnMap);
            FriendNotificationCommand = new RelayCommand<String>(ShowFriendNotification);
        }

        public override void Update()
        {
            base.Update();
            GetFriends();
        }

        /// <summary>
        /// Ophalen van een lijst met vrienden
        /// </summary>
        private void GetFriends()
        {
            Loading = true;
            HttpGet friendsHttpGet = new HttpGet(String.Format(GlobalHelper.Url + "GetFriendList/{0}", UserHelper.Token), typeof(GetFriendListResult));
            friendsHttpGet.FinishedGet += friendsHttpGet_FinishedGet;
        }

        private void friendsHttpGet_FinishedGet(object sender, EventArgs e)
        {
            try
            {
                HttpGet get = sender as HttpGet;
                if (get == null || get.resultObject == null)
                    return;


                GetFriendListResult result = ((GetFriendListResult)get.resultObject);
                if (result == null)
                    throw new Exception("no result.");

                List<Friend> friendsList = result.Friends;

                if (friendsList == null)
                    throw new Exception("no result list");

                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    Friends.Clear();
                    foreach (Friend friend in friendsList)
                    {
                        if (friend.LastSeenTimestamp != null && friend.LastSeenTimestamp != new DateTime())
                        {
                            DateTime? oldTimeStamp = friend.LastSeenTimestamp;
                            DateTime timeStamp = new DateTime(oldTimeStamp.Value.Year, oldTimeStamp.Value.Month, oldTimeStamp.Value.Day, oldTimeStamp.Value.Hour, oldTimeStamp.Value.Minute, oldTimeStamp.Value.Second, oldTimeStamp.Value.Millisecond, DateTimeKind.Utc);
                            friend.LastSeenTimestamp = timeStamp.ToLocalTime();
                        }
                        
                        Friends.Add(friend);
                        DetermineFriendsLocation(friend);
                    }
                    OnPropertyChanged("Friends");
                });
            }
            catch (Exception ex)
            {

            }
            finally
            {
                Loading = false;
            }
        }         

        /// <summary>
        /// Tonen van het profiel van een vriend
        /// </summary>
        /// <param name="obj">PersonNearby of string met username</param>
        private void DoShowProfile(Object obj)
        {
            if (obj == null)
                return;

            String username = "";


            if (obj is PersonNearby && (obj as PersonNearby).profilePrivacy == PrivacyEnum.Public)
                username = (obj as PersonNearby).Username;

            if(obj is String && !String.IsNullOrEmpty((String)obj))
                username = (String)obj;

            if(!String.IsNullOrEmpty(username))
                NavigationHelper.NavigateTo(String.Format("/UserInterface/Pages/ProfilePage.xaml?username={0}", username));
        }

        /// <summary>
        /// Toon de notificatie die op deze vriend is ingesteld
        /// </summary>
        /// <param name="username">Gebruikersnaam van de vriend</param>
        private void ShowFriendNotification(String username)
        {
            ControllerHelper.FriendNotificationController.Load(username);
            NavigationHelper.NavigateTo("/UserInterface/Pages/FriendNotificationPage.xaml");
        }

        /// <summary>
        /// Start een conversatie met een vriend
        /// </summary>
        /// <param name="username">Gebruikersnaam van de vriend</param>
        private void Chat(String username)
        {
            ControllerHelper.ConversationsController.ChatWith(username); 
        }

        /// <summary>
        /// Bepaal de locatie tekst voor de vriend aan de hand van de eigen locatie
        /// </summary>
        /// <param name="friend">Vriend object</param>
        private void DetermineFriendsLocation(Friend friend)
        {
            if (friend == null)
                return;

            UserLocationData currentLocationData = LocationManager.CurrentLocationData;
            String displayText = "";
            if (friend.Location != null && friend.Location.Distance != 0)
            {
                double distance = friend.Location.Distance;
                if (distance < 1)
                {
                    distance *= 1000;
                    if (distance < 1)
                    {
                        distance *= 1000;
                        AppendDisplayText(ref displayText, ((Convert.ToInt32(distance)).ToString() + " cm"));
                    }
                    else
                        AppendDisplayText(ref displayText, ((Convert.ToInt32(distance)).ToString() + " m"));
                }
                else
                    AppendDisplayText(ref displayText, ((Convert.ToInt32(distance)).ToString() + " km"));

            }
            if (friend.Location != null && !String.IsNullOrEmpty(friend.Location.AddressLine))
                AppendDisplayText(ref displayText, friend.Location.AddressLine);
            if (currentLocationData != null)
            {
                if (friend.Location != null && !String.IsNullOrEmpty(friend.Location.Locality) && friend.Location.Locality != currentLocationData.Locality)
                    AppendDisplayText(ref displayText, friend.Location.Locality);
                if (friend.Location != null && !String.IsNullOrEmpty(friend.Location.CountryRegion) && friend.Location.CountryRegion != currentLocationData.CountryRegion)
                    AppendDisplayText(ref displayText, "\n" + friend.Location.CountryRegion);
            }
            else
            {
                if (friend.Location != null && !String.IsNullOrEmpty(friend.Location.Locality))
                    AppendDisplayText(ref displayText, friend.Location.Locality);
                if (friend.Location != null && !String.IsNullOrEmpty(friend.Location.CountryRegion))
                    AppendDisplayText(ref displayText, "\n" + friend.Location.CountryRegion);
            }

            if(friend.Location != null)
                friend.Location.DisplayablePosition = displayText;
        }

        private void AppendDisplayText(ref String displaytext, String text)
        {
            if (displaytext == null || text == null)
                return;

            if (displaytext == String.Empty)
                displaytext = text;
            else
                displaytext += (", " + text);
        }

        /// <summary>
        /// Verwijder een vriend
        /// </summary>
        /// <param name="username">Gebruikersnaam van de vriend</param>
        private void RemoveFriend(String username)
        {
            Loading = true;
            ControllerHelper.ConversationsController.DeleteChat(username);
            HttpGet removeFriendHttpGet = new HttpGet(String.Format(GlobalHelper.Url + "RemoveFriend/{0}/{1}", UserHelper.Token, username), typeof(RemoveFriendResult));
            removeFriendHttpGet.FinishedGet += new EventHandler(removeFriendHttpGet_FinishedGet);
        }

        private void removeFriendHttpGet_FinishedGet(object sender, EventArgs e)
        {
            try
            {
                HttpGet get = sender as HttpGet;
                if (get != null && (get.resultObject as RemoveFriendResult) != null)
                {
                    RemoveFriendResult result = get.resultObject as RemoveFriendResult;
                    if (result.TokenValidationResult == TokenValidationResultEnum.Valid && result.Result != null)
                    {
                        switch (result.Result)
                        {
                            case RemoveFriendResultEnum.Succes:
                                GlobalHelper.ShowMessage("", "Succesfully removed.");
                                ControllerHelper.FriendController.Update();
                                break;
                            case RemoveFriendResultEnum.UserIsNotAFriend:
                                GlobalHelper.ShowMessage("Error", "User is not a friend.");
                                break;
                            case RemoveFriendResultEnum.UserNotExists:
                                GlobalHelper.ShowMessage("Error", "User doesn't exist.");
                                break;
                        }
                    }
                    else if (result.TokenValidationResult == TokenValidationResultEnum.Invalid) 
                    { 

                    }
                }
            }
            catch (Exception ex){}
            finally { Loading = false; }
        }

        /// <summary>
        /// Blokkeer een vriend
        /// </summary>
        /// <param name="username">Gebruikersnaam van de vriend</param>
        private void BlockFriend(String username)
        {
            Loading = true;
            ControllerHelper.ConversationsController.DeleteChat(username);
            HttpGet blockFriendHttpGet = new HttpGet(GlobalHelper.Url + String.Format("BlockFriend/{0}/{1}", UserHelper.Token, username), typeof(BlockFriendResult));
            blockFriendHttpGet.FinishedGet += blockFriendHttpGet_FinishedGet;
        }

        private void blockFriendHttpGet_FinishedGet(object sender, EventArgs e)
        {
            try 
            {
                HttpGet get = sender as HttpGet;
                if (get != null && (get.resultObject as BlockFriendResult) != null)
                {
                    BlockFriendResult result = get.resultObject as BlockFriendResult;
                    if (result.TokenValidationResult == TokenValidationResultEnum.Valid && result.Result != null)
                    {
                        switch (result.Result)
                        {
                            case BlockFriendResultEnum.FriendAlreadyBlocked:
                                GlobalHelper.ShowMessage("Error", "Friend is already blocked.");
                                break;
                            case BlockFriendResultEnum.NotAFriend:
                                GlobalHelper.ShowMessage("Error", "Person is not a friend.");
                                break;
                            case BlockFriendResultEnum.Succes:
                                ControllerHelper.FriendController.Update();
                                GlobalHelper.ShowMessage("", "Friend succesfully blocked.");
                                break;
                            case BlockFriendResultEnum.UserNotExists:
                                GlobalHelper.ShowMessage("Error", "User doesn't exist.");
                                break;
                        }
                    }
                    else if (result.TokenValidationResult == TokenValidationResultEnum.Invalid)
                    {

                    }
                }
            }
            catch (Exception ex) { }
            finally { Loading = false; }
        }

        /// <summary>
        /// Deblokkeer een vriend
        /// </summary>
        /// <param name="username">Gebruikersnaam van de vriend</param>
        private void UnblockFriend(String username)
        {
            Loading = true;
            HttpGet unblockFriendHttpGet = new HttpGet(GlobalHelper.Url + String.Format("UnblockFriend/{0}/{1}", UserHelper.Token, username), typeof(UnblockFriendResult));
            unblockFriendHttpGet.FinishedGet += unblockFriendHttpGet_FinishedGet;
        }

        private void unblockFriendHttpGet_FinishedGet(Object sender, EventArgs e)
        {
            try
            {
                HttpGet get = sender as HttpGet;
                if (get != null && (get.resultObject as UnblockFriendResult) != null)
                {
                    UnblockFriendResult result = get.resultObject as UnblockFriendResult;
                    if (result.TokenValidationResult == TokenValidationResultEnum.Valid && result.Result != null)
                    {
                        switch (result.Result)
                        {
                            case UnblockFriendResultEnum.FriendNotBlocked:
                                GlobalHelper.ShowMessage("Error", "Friend is not blocked.");
                                break;
                            case UnblockFriendResultEnum.NotAFriend:
                                GlobalHelper.ShowMessage("Error", "Person is not a friend.");
                                break;
                            case UnblockFriendResultEnum.Succes:
                                ControllerHelper.FriendController.Update();
                                GlobalHelper.ShowMessage("", "Friend succesfully unblocked.");
                                break;
                            case UnblockFriendResultEnum.UserNotExists:
                                GlobalHelper.ShowMessage("Error", "User doesn't exist.");
                                break;
                        }
                    }
                    else if (result.TokenValidationResult == TokenValidationResultEnum.Invalid)
                    {

                    }
                }
            }
            catch (Exception ex) { }
            finally { Loading = false; }
        }

        /// <summary>
        /// Navigeer naar de pagina waar de vrienden op de map getoond worden
        /// </summary>
        private void ShowFriendsOnMap()
        {
            NavigationHelper.NavigateTo("/UserInterface/Pages/MapPage.xaml?MapMode=AllFriends");
        }
    }
}
